home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / flight / uflight.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  700 lines

  1. /*
  2.  * Copyright 1984-1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*
  19.  *  flight/uflight.c $Revision: 1.26 $
  20.  */
  21.  
  22. #include "flight.h"
  23. #include "light.h"
  24. #include "colors.h"
  25. #include <math.h>
  26.  
  27.  
  28. void my_lookat(float vx, float vy, float vz, float px, float py, float pz,
  29.            Matrix resmat)
  30. {
  31.     float sine, cosine, hyp, hyp1, dx, dy, dz;
  32.     static Matrix mat = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
  33.  
  34.     dx = px - vx;
  35.     dy = py - vy;
  36.     dz = pz - vz;
  37.  
  38.     hyp = dx * dx + dz * dz;    /* hyp squared    */
  39.     hyp1 = sqrt(dy*dy + hyp);
  40.     hyp = sqrt(hyp);        /* the real hyp    */
  41.  
  42.     if (hyp1 != 0.0)        /* rotate X    */
  43.     {
  44.     sine = -dy / hyp1;
  45.     cosine = hyp / hyp1;
  46.     }
  47.     else
  48.     {
  49.     sine = 0.0;
  50.     cosine = 1.0;
  51.     }
  52.     mat[1][1] = resmat[1][1] = cosine;        /* rotate X    */
  53.     mat[1][2] = resmat[2][1] = sine;
  54.     mat[2][1] = resmat[1][2] = -sine;
  55.     mat[2][2] = resmat[2][2] = cosine;
  56.     multmatrix(mat);
  57.     mat[1][1] = 1.0;
  58.     mat[1][2] = 0.0;
  59.     mat[2][1] = 0.0;
  60.  
  61.     if (hyp != 0.0)        /* rotate Y    */
  62.     {
  63.     sine = dx / hyp;
  64.     cosine = -dz / hyp;
  65.     }
  66.     else
  67.     {
  68.     sine = 0.0;
  69.     cosine = 1.0;
  70.     }
  71.     mat[0][0] = cosine;        /* rotate Y    */
  72.     mat[0][2] = -sine;
  73.     mat[2][0] = sine;
  74.     mat[2][2] = cosine;
  75.     multmatrix(mat);
  76.     mat[0][2] = sine;
  77.     mat[2][0] = -sine;
  78.     matrix_post_multiply(mat, resmat);
  79.     mat[0][0] = 1.0;
  80.     mat[0][2] = 0.0;
  81.     mat[2][0] = 0.0;
  82.     translate(-vx, -vy, -vz);            /* translate viewpoint */
  83. }
  84.  
  85.  
  86. void set_f14_form(Plane pp)
  87. {
  88.     int pos;
  89.  
  90.     /*
  91.      * set wing position
  92.      */
  93.     if (pp->airspeed < 240)
  94.     {
  95.     setrotation(planeobj[F14], 2, -pp->airspeed/12, 'y');
  96.     setrotation(planeobj[F14], 3, pp->airspeed/12, 'y');
  97.     }
  98.     else if (pp->airspeed <= 450)
  99.     {
  100.     setrotation(planeobj[F14], 2, -20, 'y');
  101.     setrotation(planeobj[F14], 3, 20, 'y');
  102.     }
  103.     else if (pp->airspeed >= 720)
  104.     {
  105.     setrotation(planeobj[F14], 2, -480, 'y');
  106.     setrotation(planeobj[F14], 3, 480, 'y');
  107.     }
  108.     else
  109.     {
  110.     setrotation(planeobj[F14], 2,
  111.             (int)((pp->airspeed-450)*-1.704)-20, 'y');
  112.     setrotation(planeobj[F14], 3,
  113.             (int)((pp->airspeed-450)*1.704)+20, 'y');
  114.     }
  115.  
  116.     /*
  117.      * set tailplane position
  118.      */
  119.     pos = (int)(pp->elevator/2.5 + (pp->rollers>>2));
  120.     if (pos > 200)
  121.     pos = 200;
  122.     else if (pos < -200)
  123.     pos = -200;
  124.     setrotation(planeobj[F14], 16, pos, 'x');    /* left tailplane */
  125.     pos = (int)(pp->elevator/2.5 - (pp->rollers>>2));
  126.     if (pos > 200)
  127.     pos = 200;
  128.     else if (pos < -200)
  129.     pos = -200;
  130.     setrotation(planeobj[F14], 15, pos, 'x');    /* right tailplane */
  131.  
  132.     /*
  133.      * set thrust
  134.      */
  135.     if (pp->thrust <= 0)
  136.     setscale(planeobj[F14], 5, 1.0, 1.0, 0.01);
  137.     else
  138.     setscale(planeobj[F14], 5, 1.0, 1.0, pp->thrust/100.0);
  139.  
  140.     /*
  141.      * set wheel position
  142.      */
  143.     setrotation(planeobj[F14], 7, pp->wheels*90, 'x');
  144.     setrotation(planeobj[F14], 10, pp->wheels*90, 'y');
  145.     setrotation(planeobj[F14], 11, -pp->wheels*90, 'y');
  146. }
  147.  
  148.  
  149. void set_f15_form(Plane pp)
  150. {
  151.     int pos;
  152.  
  153.     /*
  154.      * set tailplane position
  155.      */
  156.     pos = (int)(pp->elevator/2.5 + (pp->rollers>>2));
  157.     if (pos > 200)
  158.     pos = 200;
  159.     else if (pos < -200)
  160.     pos = -200;
  161.     setrotation(planeobj[F15], 16, pos, 'x');    /* left tailplane */
  162.     pos = (int)(pp->elevator/2.5 - (pp->rollers>>2));
  163.     if (pos > 200)
  164.     pos = 200;
  165.     else if (pos < -200)
  166.     pos = -200;
  167.     setrotation(planeobj[F15], 15, pos, 'x');    /* right tailplane */
  168.  
  169.     /*
  170.      * set thrust
  171.      */
  172.     if (pp->thrust <= 0)
  173.     setscale(planeobj[F15], 5, 1.0, 1.0, 0.01);
  174.     else
  175.     setscale(planeobj[F15], 5, 1.0, 1.0, pp->thrust/100.0);
  176.  
  177.     /*
  178.      * set wheel position
  179.      */
  180.     setrotation(planeobj[F15], 7, pp->wheels*90, 'x');
  181.     setrotation(planeobj[F15], 10, pp->wheels*90, 'y');
  182.     setrotation(planeobj[F15], 11, -pp->wheels*90, 'y');
  183. }
  184.  
  185.  
  186. void set_f18_form(Plane pp)
  187. {
  188.     float percent, ipercent, spercent;
  189.     float a, b;
  190.     int pos;
  191.  
  192.     /*
  193.      * set landing gear position
  194.      */
  195.     percent = pp->wheels/10.0;
  196.     ipercent = 1.0 - percent;
  197.  
  198.     setrotation(planeobj[F18],  7, (int)( 100 * ipercent),       'z');
  199.     setrotation(planeobj[F18],  8, (int)(-900 *  percent - 100), 'x');
  200.     setrotation(planeobj[F18],  9, (int)( 650 *  percent + 250), 'y');
  201.  
  202.     if (pp->y - 4.565 >= 2.3)
  203.     spercent = 0.0;
  204.     else if (pp->y - 4.565 == 0)
  205.     spercent = ipercent;
  206.     else
  207.     {
  208.     spercent = 1.0 - ((pp->y - 4.565) / 2.3);
  209.     spercent = (spercent < ipercent)? spercent : ipercent;
  210.     }
  211.  
  212.     setrotation(planeobj[F18], 10, (int)(-800 * spercent),       'x');
  213.     setrotation(planeobj[F18], 11, (int)( 800 * spercent),       'x');
  214.     setrotation(planeobj[F18], 12, (int)(-650 *  percent - 250), 'y');
  215.     setrotation(planeobj[F18], 13, (int)( 100 * ipercent),       'x');
  216.     setrotation(planeobj[F18], 14, (int)(-100 * ipercent),       'z');
  217.     setrotation(planeobj[F18], 15, (int)( 250 * ipercent),       'y');
  218.     setrotation(planeobj[F18], 16, (int)(-250 * ipercent),       'y');
  219.     setrotation(planeobj[F18], 17, (int)(-100 *  percent),       'z');
  220.     setrotation(planeobj[F18], 18, (int)( 100 *  percent),       'z');
  221.     setrotation(planeobj[F18], 21, (int)(1000 *  percent),       'x');
  222.  
  223.     a = pp->y - 4.565;
  224.     if (pp->elevation > 0)
  225.     b = pp->elevation / 60.0;
  226.     else
  227.     b = 0;
  228.     a = (a > b)? a : b;
  229.     a = (a > 1.0)? 1.0 : b;
  230.  
  231.     settranslation(planeobj[F18], 20, 0.0 ,-1.4 - a ,0.0);
  232.  
  233.  
  234.     /*
  235.      * set tailplane position
  236.      */
  237.     pos = (int)(pp->elevator/2.5 + (pp->rollers>>2));
  238.     if (pos > 200)
  239.     pos = 200;
  240.     else if (pos < -200)
  241.     pos = -200;
  242.     setrotation(planeobj[F18], 23, pos, 'x');    /* left tailplane */
  243.     pos = (int)(pp->elevator/2.5 - (pp->rollers>>2));
  244.     if (pos > 200)
  245.     pos = 200;
  246.     else if (pos < -200)
  247.     pos = -200;
  248.     setrotation(planeobj[F18], 24, pos, 'x');    /* left tailplane */
  249.  
  250.     /*
  251.      * set thrust
  252.      */
  253.     if (pp->thrust <= 0)
  254.     setscale(planeobj[pp->type], 27, 1.0, 1.0, 0.01);
  255.     else
  256.     setscale(planeobj[pp->type], 27, 1.0, 1.0, pp->thrust/100.0);
  257. }
  258.  
  259.  
  260. void set_p38_form(Plane pp)
  261. {
  262.     setrotation(planeobj[P38], 0, -pp->wheels*100, 'x');
  263. }
  264.  
  265.  
  266. void set_ci_f16_form(Plane pp)
  267. {
  268.     int pos;
  269.  
  270.     /*
  271.      * set wheel position
  272.      */
  273.     setrotation(planeobj[F16], 0, pp->wheels*100, 'x');
  274.     if (pp->wheels < 5)
  275.     {
  276.     setrotation(planeobj[F16], 4, -pp->wheels*100, 'y');
  277.     setrotation(planeobj[F16], 6,  pp->wheels*100, 'y');
  278.     }
  279.     else
  280.     {
  281.     setrotation(planeobj[F16], 4, -500, 'y');
  282.     setrotation(planeobj[F16], 6,  500, 'y');
  283.     }
  284. }
  285.  
  286.  
  287.  
  288.  
  289. /*
  290.  *  draw the planes and their shadows that are visible
  291.  */
  292. void draw_planes(float ex, float ey, float ez,
  293.          int start_plane, int num_planes)
  294. {
  295.     int i, close, x, z;
  296.     register Plane pp;
  297.  
  298.     /*
  299.      *  always draw my shadow
  300.      */
  301.     if (start_plane > 0)
  302.     {
  303.     draw_shadow(planes[0], TRUE);
  304.     if (planes[0]->status <= MEXPLODE && planes[0]->status)
  305.     {
  306.         lsuspend(TRUE);
  307.         pushmatrix();
  308.         translate(planes[0]->x, planes[0]->y, planes[0]->z);
  309.         draw_exp(19 - (planes[0]->status - 1));
  310.         popmatrix();
  311.         lsuspend(FALSE);
  312.     }
  313.     }
  314.  
  315.     for (i = start_plane; i < num_planes; i++)
  316.     {
  317.     pp = planes[i];
  318.  
  319.     z = ez - (int)pp->z;
  320.     x = ex - (int)pp->x;
  321.     if (z < 0) z = -z;
  322.     if (x < 0) x = -x;
  323.     if (x < 1024000 && z < 1024000)
  324.     {
  325.         x >>= 5;
  326.         z >>= 5;
  327.         close = ((x * x + z * z) < (dist_for_lines<<1));
  328.  
  329.         if (pp->y < 5000.0)
  330.         draw_shadow(pp, close);
  331.  
  332.         /*
  333.          *  If the plane is not visible don't draw it.
  334.          */
  335.         if (cull_sphere(&pp->x, planeobj[pp->type]->radius))
  336.         continue;
  337.  
  338.         pushmatrix();
  339.         translate(pp->x, pp->y, pp->z);
  340.         rotate(pp->azimuth, 'y');
  341.         rotate(pp->elevation, 'x');
  342.         rotate(pp->twist, 'z');
  343.  
  344.         if (close)    /* if close enough */
  345.         {
  346.         switch(pp->type)
  347.         {
  348.             case F15:
  349.             set_f15_form(pp);
  350.             break;
  351.             case F18:
  352.             set_f18_form(pp);
  353.             break;
  354.             case F14:
  355.             set_f14_form(pp);
  356.             break;
  357.             case P38:
  358.             set_p38_form(pp);
  359.             break;
  360.         }
  361.         drawobj(planeobj[pp->type],
  362.             PS_MAINBODY | ((pp->wheels != 10)? PS_LANDINGGEAR : 0) |
  363.             (pp->weapon_state << PS_W_SHIFT));
  364.         }
  365.         else
  366.         drawobj(planeobj[pp->type],
  367.             PS_FAR | (pp->weapon_state << PS_W_SHIFT));
  368.  
  369.         if (pp->status <= MEXPLODE && pp->status)  /* explosion if needed */
  370.         {
  371.         lsuspend(TRUE);
  372.         draw_exp(19 - (pp->status - 1));
  373. #ifdef AUDIO
  374.         if (pp->status == MEXPLODE - 1)   /* first frame of expl. */
  375.             play_explosion((ex - pp->x)*(ex - pp->x) +
  376.             (ey - pp->y)*(ey - pp->y) +
  377.             (ez - pp->z)*(ez - pp->z));
  378. #endif
  379.         lsuspend(FALSE);
  380.         }
  381.  
  382.         popmatrix();
  383.     }
  384.     }
  385. }
  386.  
  387.  
  388.  
  389. void draw_missiles()
  390. {
  391.     register Plane p, *pp;
  392.     register Plane_hist ph, *pph;
  393.     int i, j;
  394.  
  395.     linewidth(2);
  396.     FOR_EACH_PLANE_AND_HIST (p, pp, ph, pph)
  397.     draw_missile(p, ph);
  398.     linewidth(1);
  399. }
  400.  
  401.  
  402. #define BUILDINGS_X -325
  403. #define BUILDINGS_Z -2750
  404.  
  405. void draw_buildings(float ex, float ey, float ez)
  406. {
  407.     int x, y, z;
  408.  
  409.     x = ex + BUILDINGS_X;
  410.     if (x < 0)
  411.     x = -x;
  412.     y = ey;
  413.     z = ez + BUILDINGS_Z;
  414.     if (z < 0)
  415.     z = -z;
  416.  
  417.     x >>= 5;
  418.     y >>= 5;
  419.     z >>= 5;
  420.  
  421.     drawobj(buildingsobj,
  422.         ((x*x + y*y + z*z) < (dist_for_lines<<3)) ? BUILDING_NEAR :
  423.                             BUILDING_FAR );
  424. }
  425.  
  426.  
  427. void draw_threats()
  428. {
  429.     pushmatrix();
  430.     settranslation(threatobj, 0, 6000.0, 0.0, 14000.0);
  431.     setscale(threatobj, 1, 17000.0, 17000.0, 17000.0);
  432.     drawobj(threatobj, 0x1);
  433.     popmatrix();
  434.  
  435.     pushmatrix();
  436.     settranslation(threatobj, 0, -20000.0, 0.0, 15000.0);
  437.     setscale(threatobj, 1, 10700.0, 10700.0, 10700.0);
  438.     drawobj(threatobj, 0x1);
  439.     popmatrix();
  440.  
  441.     pushmatrix();
  442.     settranslation(threatobj, 0, 3000.0, 0.0, 34000.0);
  443.     setscale(threatobj, 1, 2700.0, 2700.0, 2700.0);
  444.     drawobj(threatobj, 0x1);
  445.     popmatrix();
  446. }
  447.  
  448.  
  449. void draw_everything(float ex, float ey, float ez,
  450.              int numplanes, int draw_self)
  451. {
  452.     int i, count;
  453.     float tx, ty, tz;
  454.     Matrix tempmat;
  455.     Plane pp;
  456.     int close;
  457.  
  458.     obj_list_t *draw_list[MAX_OBJS+2*MAX_PLANES];
  459.     float dist[MAX_OBJS+2*MAX_PLANES];
  460.  
  461.     /*
  462.      *  add buildings, threats, etc.
  463.      */
  464.     for (i=0, count=0; i < obj_count; i++, count++)
  465.     {
  466.     tx = ex - sort_obj[i].cx;
  467.     tz = ez - sort_obj[i].cz;
  468.     dist[count] = (tx * tx) + (tz * tz);
  469.     draw_list[count] = &sort_obj[i];
  470.     }
  471.  
  472.     /*
  473.      *  add planes
  474.      */
  475.     for (i = 0; i < numplanes; i++)
  476.     {
  477.     pp = planes[i];
  478.  
  479.     if (i != 0 || draw_self)
  480.     {
  481.         /*
  482.          *  calculate distance from eye to plane
  483.          */
  484.         tx = ex - pp->x;
  485.         ty = ey - pp->y;
  486.         tz = ez - pp->z;
  487.         dist[count] = (tx*tx) + (tz*tz);
  488.         sort_plane[i].obj = planeobj[pp->type];
  489.         draw_list[count] = &sort_plane[i];
  490.  
  491.         /*
  492.          *  figure out what mode to draw in
  493.          */
  494.         if (dist[count] > (float)dist_for_lines * (1<<12))
  495.         {
  496.         sort_plane[i].mode = PS_FAR;
  497.         }
  498.         else
  499.         {
  500.         /*
  501.          *  calculate eightview
  502.          */
  503.         sort_plane[i].mode = PS_MAINBODY;
  504.         identify_matrix(tempmat);
  505.         matrix_rotate(tempmat, -pp->twist, 'z');
  506.         matrix_rotate(tempmat, -pp->elevation, 'x');
  507.         matrix_rotate(tempmat, -pp->azimuth, 'y');
  508.         matrix_translate(tempmat, tx, ty, tz);
  509.         if (tempmat[3][0] >= 0.0) sort_plane[i].mode |= EV_RIGHT;
  510.         if (tempmat[3][1] >= 0.0) sort_plane[i].mode |= EV_ABOVE;
  511.         if (tempmat[3][2] >= 0.0) sort_plane[i].mode |= EV_BEHIND;
  512.         }
  513.         count++;
  514.     }
  515.  
  516.     /*
  517.      *  add missile to list
  518.      */
  519.     if (pp->mstatus)
  520.     {
  521.         tz = ez - pp->mz;
  522.         tx = ex - pp->mx;
  523.         dist[count] = (tx*tx) + (tz*tz);
  524.         draw_list[count] = &sort_missile[i];
  525.         count++;
  526.     }
  527.     else
  528.     {
  529.         plane_hists[i]->malive = pp->mstatus;
  530.     }
  531.     }
  532.  
  533.     /*
  534.      *  Now sort the draw list
  535.      */
  536.     sink_sort(count, dist, (void **)draw_list);
  537.  
  538.  
  539.     /*
  540.      *  Now draw things
  541.      */
  542.  
  543.     /*
  544.      *  always draw your own shadow
  545.      */
  546.     if (!draw_self)
  547.     draw_shadow(planes[0], TRUE);
  548.  
  549.     /*
  550.      *  draw the sorted list
  551.      */
  552.     for (i=0; i < count; i++)
  553.     {
  554.     if (draw_list[i]->type == PLANE_OBJ)
  555.     {
  556.         pp = planes[draw_list[i]->id];
  557.         close = (dist[i] <= dist_for_lines);
  558.  
  559.         if (pp->y < 5000.0)
  560.         draw_shadow(pp, close);
  561.  
  562.         if (!cull_sphere(&pp->x, planeobj[pp->type]->radius))
  563.         {
  564.         pushmatrix();
  565.         translate(pp->x, pp->y, pp->z);
  566.         rotate(pp->azimuth, 'y');
  567.         rotate(pp->elevation, 'x');
  568.         rotate(pp->twist, 'z');
  569.  
  570.         if (!(draw_list[i]->mode & PS_FAR))
  571.         {
  572.             switch(pp->type)
  573.             {
  574.             case P38:
  575.                 set_p38_form(pp);
  576.                 break;
  577.             case F16:
  578.                 set_ci_f16_form(pp);
  579.                 break;
  580.             }
  581.  
  582.             drawobj(draw_list[i]->obj,
  583.                 draw_list[i]->mode |
  584.                 ((pp->wheels != 10)? PS_LANDINGGEAR : 0) |
  585.                 (pp->weapon_state << PS_W_SHIFT));
  586.         }
  587.         else
  588.             drawobj(draw_list[i]->obj, draw_list[i]->mode);
  589.  
  590.         if (pp->status <= MEXPLODE && pp->status)
  591.             draw_exp_ci(19 - (pp->status - 1));
  592.  
  593.         popmatrix();
  594.         }
  595.     }
  596.     else if (draw_list[i]->type == MISSILE_OBJ)
  597.     {
  598.         pp = planes[draw_list[i]->id];
  599.         draw_missile_ci(pp, plane_hists[draw_list[i]->id & 0x00ff]);
  600.         plane_hists[draw_list[i]->id]->malive = pp->mstatus;
  601.     }
  602.     else if (draw_list[i]->type == BUILDING_OBJ)
  603.     {
  604.         drawobj(draw_list[i]->obj,
  605.             (dist[i] < (float)dist_for_lines*(1<<13)) ? BUILDING_NEAR :
  606.                                 BUILDING_FAR);
  607.     }
  608.     else if (draw_list[i]->type == THREAT_OBJ)
  609.     {
  610.         if (threat_mode)
  611.         drawobj(draw_list[i]->obj, 1);
  612.     }
  613.     else
  614.         fprintf(stderr, "draw_everything: Error unknown obj type\n");
  615.     }
  616. }
  617.  
  618.  
  619. /*
  620.  *  add an object to the sort obj list
  621.  */
  622. void add_obj(int type, float x, float y, float z, object_t *obj)
  623. {
  624.     sort_obj[obj_count].type = type;
  625.     sort_obj[obj_count].cx = x;
  626.     sort_obj[obj_count].cy = y;
  627.     sort_obj[obj_count].cz = z;
  628.     sort_obj[obj_count].obj = obj;
  629.     obj_count++;
  630. }
  631.  
  632.  
  633. /*
  634.  *   sort an array (and an associated tag array) in decreasing order
  635.  */
  636. void sink_sort(int n, float *array, void **array_tag)
  637. {
  638.     register float tmp, *end, *top, *bot;
  639.     register void *tag, **top_tag, **bot_tag;
  640.  
  641.     end = &array[n];
  642.  
  643.     for (bot = array+1, bot_tag = array_tag+1; bot < end; bot++, bot_tag++)
  644.     {
  645.     top = bot - 1;        top_tag = bot_tag - 1;
  646.     tmp = *bot;
  647.     if (*top < tmp)
  648.     {
  649.         tag = *bot_tag;
  650.     sinktest:
  651.         top[1] = *top;    top_tag[1] = *top_tag;
  652.         top--;        top_tag--;
  653.         if (top >= array)
  654.         {
  655.         if (*top < tmp)
  656.             goto sinktest;
  657.         }
  658.  
  659.         top[1] = tmp; top_tag[1] = tag;
  660.     }
  661.     }
  662. }
  663.  
  664.  
  665. /*
  666.  *  generate a random number x, where -maxr <= x <= maxr
  667.  */
  668. int flight_random(int maxr)
  669. {
  670.     static unsigned long randx = 1;
  671.     register int n, retval;
  672.  
  673.     for (n=1; n<32; n++)
  674.     if ((1 << n) > maxr)
  675.         break;
  676.  
  677.     retval = maxr << 1;
  678.     while (retval > maxr)
  679.     {
  680.     randx = randx * 1103515245 + 12345;
  681.     retval = (randx & 0x7fffffff) >> (31-n);
  682.     }
  683.     randx = randx * 1103515245 + 12345;
  684.     if (randx & 0x40000000)
  685.     return(retval);
  686.     else
  687.     return(-retval);
  688. }
  689.  
  690.  
  691. float range(float x1, float y1, float z1, float x2, float y2, float z2)
  692. {
  693.     float x, y, z;
  694.  
  695.     x = fabs(x1 - x2);
  696.     y = fabs(y1 - y2);
  697.     z = fabs(z1 - z2);
  698.     return(sqrt(x*x + y*y + z*z));
  699. }
  700.